package com.thesharegame.pricing.engine;

import java.util.ArrayList;
import java.util.List;

import com.thesharegame.dal.DALService;
import com.thesharegame.model.Market;
import com.thesharegame.model.Stock;
import com.thesharegame.pricing.provider.PriceProvider;
import com.thesharegame.pricing.provider.ProvidersRegistry;

public class UpdatePricesJob implements Runnable {

	private DALService service;
	
	public UpdatePricesJob(){
		service = new DALService();
	}
	
	@Override
	public void run() {
		try {
			while (!Thread.currentThread().isInterrupted()) {
				ProvidersRegistry registry = ProvidersRegistry.getInstance();
				List<Class<? extends PriceProvider>> providers = registry.getProivders();

				for (Class<? extends PriceProvider> clazz : providers) {
					System.out.println("Instantiating provider");
					PriceProvider provider = clazz.newInstance();
					System.out.println("Fetching market");
					Market market = this.getMarket(provider);
					System.out.println("Getting stocks");
					List<Stock> stocks = provider.getStockPrices();
					System.out.println("Merging stocks");
					List<Stock> merged = this.mergeStocks(stocks);
					market.getStocks().clear();
					market.addStocks(merged);
					System.out.println("Saving objects");
					service.saveObjects(merged);
					service.saveObject(market);
				}
				Thread.sleep(1800000);
			}
		} catch (InterruptedException e) {
			// good practice
			Thread.currentThread().interrupt();
			return;

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private List<Stock> mergeStocks(List<Stock> stocks){
		List<Stock> results = new ArrayList<Stock>();
		for(Stock stock : stocks){
			List<Object> fetchResults = service.fetch(stock);
			if(fetchResults.isEmpty()){
				results.add(stock);
			}else{
				results.add((Stock)fetchResults.get(0));
			}
		}
		return results;
	}

	private Market getMarket(PriceProvider provider) {
		String marketSymbol = provider.getMarketSymbol();
		String marketName = provider.getMarketName();
		Market prototype = new Market();
		prototype.setSymbol(marketSymbol);
		List<Object> result = service.fetch(prototype);
		if(result.isEmpty()){
			prototype.setName(marketName);
			service.saveObject(prototype);
			return prototype;
		}else{
			return (Market)result.get(0);
		}
	}

}
